package com.mooc.ppjoke.ui;

import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModel;
import androidx.paging.DataSource;
import androidx.paging.LivePagedListBuilder;
import androidx.paging.PagedList;

/**
 * 通用的数据处理
 * @param <T>
 */
public abstract class AbsViewModel<T> extends ViewModel {
    protected PagedList.Config config;
    private DataSource dataSource;
    private LiveData<PagedList<T>> pageData;
    private MutableLiveData<Boolean> boundaryPageData = new MutableLiveData<>();

    public AbsViewModel() {
        config = new PagedList.Config.Builder()
                .setPageSize(10)
                .setInitialLoadSizeHint(12)
                // .setMaxSize(100)；
                //.setEnablePlaceholders(true)；设置了加载的总数据才会起作用，如果设置了总共加载100条数据，然后初始的时候加载了10条，
//                当我们滑到11、12、13条的时候，由于数据还没加载完成，PagedList会把剩下的数据用占位符来代替。
                // .setEnablePlaceholders(false)
                // 告诉PageList距离屏幕底部还有几个item的时候，就开始加载下一页。理论上应该是屏幕上可见item的数倍，如果没有设置，默认是page size大小。
//                如果设置了PageSize是10，那么PrefetchDistance默认也是10。如果setInitialLoadSizeHint(10)，当加载初始化数据成功的时候，有了10条数据，
//                由于PageSize和PrefetchDistance也是10，那么就会立马加载下一页。如果不想初始化数据加载完成之后里面加载下一页数据，
//                可以将setInitialLoadSizeHint设置成比PageSize稍大一些
//                 .setPrefetchDistance()
                .build();

        pageData = new LivePagedListBuilder(factory, config)
                .setInitialLoadKey(0)//加载初始化数据需要传递的参数
                //.setFetchExecutor()//给PageList提供一个执行异步任务的线程池，一般不需要调用，Paging框架内置
                .setBoundaryCallback(callback)//可以监听PagedList数据加载的状态
                .build();
    }


    public LiveData<PagedList<T>> getPageData() {
        return pageData;
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    public LiveData<Boolean> getBoundaryPageData() {
        return boundaryPageData;
    }

    //PagedList数据被加载情况的边界回调callback
    //但不是每一次分页都会回调这里，具体请看 ContiguousPagedList#mReceiver#onPageResult
    //deferBoundaryCallbacks
    PagedList.BoundaryCallback<T> callback = new PagedList.BoundaryCallback<T>() {
        @Override
        public void onZeroItemsLoaded() {
            //新提交的PagedList中没有数据
            boundaryPageData.postValue(false);
        }

        @Override
        public void onItemAtFrontLoaded(@NonNull T itemAtFront) {
            //新提交的PagedList中第一条数据被加载到列表上
            boundaryPageData.postValue(true);
        }

        @Override
        public void onItemAtEndLoaded(@NonNull T itemAtEnd) {
            //新提交的PagedList中最后一条数据被加载到列表上
        }
    };

    DataSource.Factory factory = new DataSource.Factory() {
        @NonNull
        @Override
        public DataSource create() {
            if (dataSource == null || dataSource.isInvalid()) {
                dataSource = createDataSource();
            }
            return dataSource;
        }
    };

    public abstract DataSource createDataSource();


    //可以在这个方法里 做一些清理 的工作
    @Override
    protected void onCleared() {

    }
}
